/*
 * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Oracle or the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */ 

package presentacion.utilidad;

/*
 * Imprimir.java requires the following files:
 * toprint.txt
 * guide.txt
 * images/print.png
 */

import hibernate.objeto.Paciente;
import java.awt.Dimension;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.print.PrinterException;
import javax.swing.*;
import java.text.MessageFormat;
import presentacion.CapaPresentacion;
import presentacion.utilidad.maquetado.Fuente;
import presentacion.utilidad.maquetado.Icono;


public class Imprimir extends javax.swing.JDialog {
    
    public Imprimir(java.awt.Frame parent, boolean modal, String textoAImprimir,
            Paciente paciente) {
        
        super(parent, modal);
        initComponents();
        setLocationRelativeTo(null);
        
        this.paciente = paciente;
        this.textoAImprimir = textoAImprimir;

        setearEventosQueCapturanTeclaEnterYEscape();

        personalizarGUI();
    }
    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
    private void initComponents() {
        this.setPreferredSize(new Dimension(1024, 690));
        this.setResizable(false);

        jScrollPane1 = new javax.swing.JScrollPane();
        text = new javax.swing.JTextPane();
        headerLabel = new javax.swing.JLabel();
        headerField = new javax.swing.JTextField();
        footerLabel = new javax.swing.JLabel();
        footerField = new javax.swing.JTextField();
        interactiveCheck = new javax.swing.JCheckBox();
        printButton = new javax.swing.JButton();
        guideText = new javax.swing.JTextArea();
        backgroundCheck = new javax.swing.JCheckBox();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setTitle("Area de impresión");

	text.setContentType("text/html");
        text.setEditable(false);
        text.setFont(Fuente.FUENTE_TEXTFIELD);
        text.setForeground(Fuente.COLOR_NORMAL);
        text.setText("<html>    <head>      </head>    <body>      <p style=\"margin-top: 0\">              </p>    </body>  </html>  ");
        text.setFocusable(false);
        text.setMinimumSize(new java.awt.Dimension(0, 0));
        text.setPreferredSize(new java.awt.Dimension(497, 220));

        jScrollPane1.setViewportView(text);

        headerLabel.setText("Cabecera");

        footerLabel.setText("Pie de página");

        footerField.setText("Página {0}");

        interactiveCheck.setSelected(true);
        interactiveCheck.setText("Mostrar progreso");
        interactiveCheck.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));

        printButton.setIcon(Icono.ICONO_16_IMPRIMIR);
        printButton.setText("Imprimir");
        printButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                print(evt);
            }
        });

        guideText.setColumns(20);
        guideText.setEditable(false);
        guideText.setLineWrap(true);
        guideText.setRows(5);
        guideText.setWrapStyleWord(true);
        guideText.setOpaque(false);

        backgroundCheck.setSelected(true);
        backgroundCheck.setText("Imprimir en segundo plano");
        backgroundCheck.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(guideText)
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(backgroundCheck, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(interactiveCheck, javax.swing.GroupLayout.PREFERRED_SIZE, 159, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(printButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                            .addComponent(footerLabel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(headerLabel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 74, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(footerField)
                            .addComponent(headerField, javax.swing.GroupLayout.PREFERRED_SIZE, 209, javax.swing.GroupLayout.PREFERRED_SIZE))))
                .addGap(15, 15, 15)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 343, Short.MAX_VALUE)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 403, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addComponent(guideText, javax.swing.GroupLayout.DEFAULT_SIZE, 260, Short.MAX_VALUE)
                        .addGap(18, 18, 18)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(headerLabel)
                            .addComponent(headerField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(footerLabel)
                            .addComponent(footerField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGap(27, 27, 27)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(interactiveCheck, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(backgroundCheck, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE))
                            .addComponent(printButton, javax.swing.GroupLayout.PREFERRED_SIZE, 52, javax.swing.GroupLayout.PREFERRED_SIZE))))
                .addContainerGap())
        );
        pack();
    }// </editor-fold>//GEN-END:initComponents

    
    private void print(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_print
        MessageFormat header = createFormat(headerField);
        MessageFormat footer = createFormat(footerField);
        boolean interactive = interactiveCheck.isSelected();
        boolean background = backgroundCheck.isSelected();

        PrintingTask task = new PrintingTask(header, footer, interactive);
        if (background) {
            task.execute();
        } else {
            task.run();
        }
    }//GEN-LAST:event_print

    private void personalizarGUI() {
        //Se setea el texto a imprimir
        text.setText(textoAImprimir);
		text.setCaretPosition(0);
        //Se setea el consejo de impresión
        guideText.setText(CapaPresentacion.IMPRESION_CONSEJO);
        if (paciente != null) {
            //Se setea la cabecera, que contiene el apellido y nombre del paciente
            //y el número de HCI
            String apellidoYNombre = paciente.getPersona().getApellidoPersona()
                    + ", " + paciente.getPersona().getNombrePersona() + ".";
            String numeroHCI = "Nº HCI: " + paciente.getIdPaciente();
            headerField.setText(apellidoYNombre + numeroHCI);
        }

        printButton.requestFocus();
    }
    
    private class PrintingTask extends SwingWorker<Object, Object> {
        private final MessageFormat headerFormat;
        private final MessageFormat footerFormat;
        private final boolean interactive;
        private volatile boolean complete = false;
        private volatile String message;
        
        public PrintingTask(MessageFormat header, MessageFormat footer,
                            boolean interactive) {
            this.headerFormat = header;
            this.footerFormat = footer;
            this.interactive = interactive;
        }
        
        @Override
        protected Object doInBackground() {
            try {
                complete = text.print(headerFormat, footerFormat,
                        true, null, null, interactive);
                message = "Imprimiendo " + (complete ? "completado" : "cancelado");
            } catch (PrinterException ex) {
                System.err.println(ex.getMessage());
                message = "Disculpe, ha ocurrido un error de impresión";
            } catch (SecurityException ex) {
                System.err.println(ex.getMessage());
                message =
                    "Disculpe, por razones de seguridad no se puede acceder a la impresora";
            }
            return null;
        }
        
        @Override
        protected void done() {
            message(!complete, message);
        }
    }
    
    private MessageFormat createFormat(JTextField source) {
        String text = source.getText();
        if (text != null && text.length() > 0) {
            try {
                return new MessageFormat(text);
            } catch (IllegalArgumentException e) {
                System.err.println(e.getMessage());
                error("Disculpe, el formato no es válido.");
            }
        }
        return null;
    }
    
    private void message(boolean error, String msg) {
        int type = (error ? JOptionPane.ERROR_MESSAGE :
                            JOptionPane.INFORMATION_MESSAGE);
        JOptionPane.showMessageDialog(this, msg, "Imprimiendo", type);
    }
    
    private void error(String msg) {
        message(true, msg);
    }

    /**
     * Setea en cada componente del JDialog los eventos que capturarán la tecla
     * enter y escape.
     */
    private void setearEventosQueCapturanTeclaEnterYEscape() {

        //Declaración del evento a capturar
        KeyListener keyListenerEscape = new KeyAdapter() {

            public void keyPressed(java.awt.event.KeyEvent evt) {
                if (evt.getKeyCode() == KeyEvent.VK_ESCAPE) {
                    //Llamada al método que capturará el boton enter y
                    //trabajará sobre el mismo
                    dispose();
                }
            }
        };
        //Setear eventos
        backgroundCheck.addKeyListener(keyListenerEscape);;
        footerField.addKeyListener(keyListenerEscape);;
        footerLabel.addKeyListener(keyListenerEscape);;
        guideText.addKeyListener(keyListenerEscape);;
        headerField.addKeyListener(keyListenerEscape);;
        headerLabel.addKeyListener(keyListenerEscape);;
        interactiveCheck.addKeyListener(keyListenerEscape);;
        jScrollPane1.addKeyListener(keyListenerEscape);;
        printButton.addKeyListener(keyListenerEscape);;
        text.addKeyListener(keyListenerEscape);;

    }
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JCheckBox backgroundCheck;
    private javax.swing.JTextField footerField;
    private javax.swing.JLabel footerLabel;
    private javax.swing.JTextArea guideText;
    private javax.swing.JTextField headerField;
    private javax.swing.JLabel headerLabel;
    private javax.swing.JCheckBox interactiveCheck;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JButton printButton;
    private javax.swing.JTextPane text;
    private Paciente paciente;
    private String textoAImprimir;
    // End of variables declaration//GEN-END:variables
}
